home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part2 / 17058 < prev    next >
Encoding:
Text File  |  1996-08-05  |  4.1 KB  |  177 lines

  1. Path: news.th-darmstadt.de!news
  2. From: enno@inferenzsysteme.informatik.th-darmstadt.de (Enno Sandner)
  3. Newsgroups: comp.lang.c++
  4. Subject: Re: Is RTTI required if polymorphic constructor exists
  5. Date: 13 Apr 1996 13:19:30 +0200
  6. Organization: Fachbereich Informatik, TH Darmstadt
  7. Sender: enno@kitz.inferenzsysteme.informatik.th-darmstadt.de
  8. Message-ID: <ltg2a874n1.fsf@kitz.inferenzsysteme.informatik.th-darmstadt.de>
  9. References: <4knh38$lbl@nuscc.nus.sg>
  10. NNTP-Posting-Host: kitz.intellektik.informatik.th-darmstadt.de
  11. In-reply-to: satrajit@iscs.nus.sg's message of 13 Apr 1996 06:20:24 GMT
  12. X-Newsreader: Gnus v5.1
  13.  
  14. In article <4knh38$lbl@nuscc.nus.sg> satrajit@iscs.nus.sg (Satrajit Sujit Ghosh) writes:
  15.  
  16.    Hi,
  17.        The following is a piece of code for run-time object registry
  18.    without the use of the RTTI library or templates. It should be pretty
  19.    simple to decipher. It creates a polymorphic constructor, without
  20.    specifying a case statement, using static initializers. 
  21.        Given this situation of object identification, is RTTI really necessary ?
  22.  
  23.    Satra[jit]
  24.    ------------------------------------------------------
  25.    http://www.iscs.nus.sg/~satrajit
  26.    Department of Information Systems and Computer Science
  27.    National University of Singapore
  28.    ======================================================
  29.  
  30.  
  31.    /*
  32.    /////////////////THE POLYMORPHIC CONSTRUCTOR///////////////////
  33.    The following code segments demonstrate the creation of a polymorphic 
  34.    constructor. 
  35.    ///////////////////////////////////////////////////////////////
  36.    */
  37.  
  38.    #include <iostream.h>
  39.    #include <string.h>
  40.  
  41.    template<class T>
  42.    class Clist{
  43.    public:
  44.      Clist(){
  45.        i = 0;
  46.      };
  47.  
  48.      void insert(char *name,T *(*func)()){
  49.        for(int j=0;j<i;j++)
  50.      // prevent re-registration
  51.      if (!strcmp(nm_arr[j],name)){
  52.        return;
  53.      }
  54.  
  55.        nm_arr[i] = strdup(name);
  56.        fun[i] = func;
  57.        i++;
  58.      }
  59.  
  60.      T* get(char *name){
  61.        int j;
  62.        for(j=0;j<i;j++)
  63.      if (!strcmp(nm_arr[j],name)){
  64.        return (*fun[j])();
  65.      }
  66.        return NULL;
  67.      };
  68.  
  69.      // currently can support 5 derived classes
  70.      char *nm_arr[5];
  71.      T *(* fun[5])();
  72.      int i;
  73.    };
  74.  
  75.  
  76.  
  77.    class CShape{
  78.    public:
  79.      virtual void print(){
  80.        cout << "reg" << endl;
  81.      };
  82.  
  83.      static CShape * mk_subclass(char *str){
  84.        return reg.get(str);
  85.      }
  86.  
  87.    protected:
  88.      static int reg_sub(char *name,CShape *(*func)()){
  89.        reg.insert(name,func);
  90.        return 0;
  91.      };
  92.  
  93.    private:  
  94.      static Clist<CShape> reg;
  95.  
  96.    };
  97.  
  98.    Clist<CShape> CShape::reg;
  99.  
  100.    class CCircle:public virtual CShape{
  101.    public:
  102.      virtual void print(){
  103.        cout <<"CCircle";
  104.      };
  105.  
  106.      static CShape* int_new(){
  107.        CShape *p = new CCircle;
  108.        return p;
  109.      };
  110.    private:
  111.      static int i;
  112.    };
  113.  
  114.    int CCircle::i = reg_sub("CCircle",&CCircle::int_new);
  115.  
  116.    class CRect:public virtual CShape{
  117.    public:
  118.  
  119.      virtual void print(){
  120.        cout <<"CRect";
  121.      };
  122.  
  123.      static CShape* int_new(){
  124.        CShape *p = new CRect;
  125.        return p;
  126.      };
  127.  
  128.    private:
  129.      static int i;
  130.    };
  131.  
  132.    int CRect::i =  reg_sub("CRect",&CRect::int_new);
  133.  
  134.    class CSquare:public virtual CRect{
  135.    public:
  136.  
  137.      virtual void print(){
  138.        cout <<"CSquare";
  139.      };
  140.  
  141.      static CShape* int_new(){
  142.        CShape *p = new CSquare;
  143.        return p;
  144.      };
  145.  
  146.    private:
  147.      static int i;
  148.    };
  149.  
  150.    int CSquare::i =  reg_sub("CSquare",&CSquare::int_new);
  151.  
  152.  
  153.    int 
  154.    main(){
  155.      CShape *fg = CShape::mk_subclass("CCircle");
  156.      cout << "Testing constructed CCircle [";
  157.      fg->print();
  158.      cout << "]\n";
  159.      CShape *fg1 = CShape::mk_subclass("CRect");
  160.      cout << "Testing constructed CRect [";
  161.      fg1->print();
  162.      cout << "]\n";
  163.      CShape *fg2 = CShape::mk_subclass("CSquare");
  164.      cout << "Testing constructed CSquare [";
  165.      fg2->print();
  166.      cout << "]\n";
  167.      return 0;
  168.    }
  169.  
  170. No, not in your example.
  171. However RTTI has other applications then assigning type-identifiers
  172. to classes. For instance if you want narrow a pointer to a virtual
  173. derived class, which doesn't work (directly) with the old-style cast,
  174. 'dynamic_cast' is much more comfortable then its emulations.
  175.  
  176.         Enno
  177.